home *** CD-ROM | disk | FTP | other *** search
- /*
- * LAPTALK terminal program
- *
- * Copyright 1991-1994 Dave Dunfield
- * All rights reserved.
- *
- * Permission granted for personal (non-commercial) use only.
- *
- * Compile with DDS MICRO-C compiler in 8086 TINY model.
- *
- * Compile command: cc laptalk -fop
- */
- #include <stdio.h>
- #include <window.h>
- #include <comm.h>
- #include <file.h>
-
- /* General definitions */
- #define FSIZE 32 /* Max. size of a file name */
- #define NFILES 8 /* Number of file entries */
- #define FWIDTH 65 /* Width of file entries */
-
- /* Script processor definitions */
- #define NUM_VARS 26 /* Number of variables allowed */
- #define CAPTURE_SIZE 256 /* Sizeof TX capture buffer */
-
- /*
- * Configuration parameters
- * These MUST all be initialized in order to have default values,
- * and to insure that they are of the same storage class.
- */
- char homedir[FSIZE+1] = 0; /* Default home directory */
- char filename[FSIZE+1] = { "*.*" }; /* Last filename accessed */
- char scriptfile[FSIZE+1]= { "*" }; /* Script file */
- int com_port = 0, /* Com port (1) */
- baud = 5, /* Baud rate (9600) */
- parity = 4, /* Parity (None) */
- dbits = 3, /* Data bits (8) */
- sbits = 0, /* Stop bits (1) */
- flow = 1; /* Flow control (Enabled) */
- int hangup_delay = 3, /* Delay to hangup modem */
- key_string_delay = 0, /* Delay between chars in TX'd strings */
- upl_char_delay = 0, /* Delay between characters on upload */
- upl_line_delay = 0, /* Delay between lines on upload */
- upl_sync_char = 0; /* Upload synchronize character */
- int tab_size = 8; /* Spacing of tab stops */
- char alarm = 0, /* Sound alarm on errors */
- echotty = 0, /* Echo data sent in tty */
- echosnd = 0, /* Echo data sent in scripts */
- sendlf = 0, /* Line-feed in ASCII upload */
- sendnull = 0, /* Send space on null lines */
- hangmdm = 0; /* Hangup modem on exit */
- int attrs[] = { /* Window attributes */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 0: Main TTY screen */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 1: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 2: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 3: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 4: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 5: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x07, /* 6: Attribute */
- WSAVE|WCOPEN|WLF|WSCROLL|WWRAP|0x70, /* 7: Attribute */
- WSAVE|WCOPEN|0x70, /* 8: Status line */
- WSAVE|WCOPEN|WBOX2|0x70, /* 9: Error Messages */
- WSAVE|WCOPEN|WBOX3|0x70, /* 10: String prompts */
- WSAVE|WCOPEN|WBOX1|0x70, /* 11: Setup screen 1 */
- WCOPEN|WBOX2|0x70 }; /* 12: Setup screen 2 */
- char protocols[NFILES][FWIDTH] = { "ASCII \\F\\A" };
- char scripts[NFILES][FWIDTH] = { 0 };
-
- /* Window attribute identifiers */
- #define TTY 0
- #define STATUS 8
- #define ERROR 9
- #define STRING 10
- #define SETUP1 11
- #define SETUP2 12
-
- /*
- * ANSI (VT100) Function key translation table
- */
- char *ansi_keys[] = {
- "\x1B[A", "\x1B[B", "\x1B[D", "\x1B[C", /* Arrow keys */
- "\x1BOR", "\x1BOS", "\x1BOP", "\x1BOQ", /* PgUp, Pgdn, Home, End */
- "\x1BOM", "\x1BOm", "\x1BOp", /* Keypad '+','-' Insert */
- "\x7F", "\x08", /* Delete & Backspace */
- "\x1BOq", "\x1BOr", "\x1BOs", "\x1BOt", /* F1, F2, F3 & F4 */
- "\x1BOu", "\x1BOv", "\x1BOw", "\x1BOx", /* F5, F6, F7 & F8 */
- "\x1BOy", "\x1BOz", /* F9 & F10 */
- "\x1BOl", "\x1BOn", 0, 0 }; /* Control: Pgup, Pgdn, Home, End */
-
- char *main_menu[] = { /* Main function menu */
- "Function menu",
- "Download file",
- "Upload file",
- "Kill capture",
- "Perform script",
- "Hangup modem",
- "Clear screen",
- "Configuration",
- "Shell to DOS",
- "Exit to DOS",
- 0 };
-
- char *config_menu[] = { /* System configuration menu */
- "General switches",
- "General parameters",
- "Serial port settings",
- "Transfer protocols",
- "Function menu scripts",
- "Video attributes",
- "Load configuration",
- "Save configuration",
- 0 }
-
- char *switches[] = { /* General switch names */
- "Sound ALARM in messages",
- "Echo data sent in tty",
- "Echo data sent in scripts",
- "Send LF on ASCII uploads",
- "Send space in NULL lines",
- "Drop DTR+RTS on EXIT" };
-
- char *serial_menu[] = { /* Serial configuration menu */
- "Comm port",
- "Baudrate",
- "Parity",
- "Data bits",
- "Stop bits",
- "Flow control",
- 0 }
-
- char *setup_form[] = { /* To set general parameters */
- 52<<8|9,
- "\x01\x00\x20Home directory:",
- "\x01\x01\x82Tab spacing:",
- "\x01\x02\x85Modem hangup delay:",
- "\x01\x03\x85String TX char delay:",
- "\x01\x04\x85ASCII Upload char delay:",
- "\x01\x05\x85ASCII Upload line delay:",
- "\x01\x06\x83ASCII Upload sync. char:",
- 0 };
-
- char *string_form[] = { /* External protocols & scripts */
- 68<<8|10,
- "\x00\x00\x401:",
- "\x00\x01\x402:",
- "\x00\x02\x403:",
- "\x00\x03\x404:",
- "\x00\x04\x405:",
- "\x00\x05\x406:",
- "\x00\x06\x407:",
- "\x00\x07\x408:",
- 0 };
-
- char *menus[] = {
- "Main TTY screen",
- "Video attribute 1",
- "Video attribute 2",
- "Video attribute 3",
- "Video attribute 4",
- "Video attribute 5",
- "Video attribute 6",
- "Video attribute 7",
- "Status line",
- "Error message box's",
- "String input fields",
- "Main menu's",
- "Sub menu's" };
-
- char *commands[] = { /* Script commands */
- "print", "echo", "assign", "equate", "input", "read", "menu", "if#",
- "ifeq", "ifne", "ifnot", "if", "goto", "skip", "stop", "call", "chain",
- "send", "scan", "flush", "wait", "upload", "download", "close", "dos",
- "visible", "invisible", "abort", "error", "message", "hangup", "terminal",
- "clear", "config", "exittodos", "rem", 0 };
-
- char *operators[] = { /* Operators in script expression parser */
- "+", "-", "*", "/", "%", "&", "|", "^", "<<", ">>",
- "==", "!=", ">=", "<=", ">", "<",
- 0 };
-
- /* Common strings */
- char uplprompt[] = { "File to UPLOAD" };
- char dnlprompt[] = { "File to DOWNLOAD" };
- char cnfprompt[] = { "Configuration filename" };
- char cnfext[] = { ".CFG" };
-
- /* Uart configuration static data tables */
- unsigned baudvalue[] =
- { _110, _300, _1200, _2400, _4800, _9600, _19200, _38400 };
- char *baudtext[] =
- { "110", "300", "1200", "2400", "4800", "9600", "19200", "38400", 0 };
- char *paritytext[] = { "Odd", "Even", "Mark", "Space", "None", 0 };
- char *onetwo[] = { "One", "Two", 0 };
- char *onefour[] = { "One", "Two", "Three", "Four", 0 };
- char *fiveight[] = { "Five", "Six", "Seven", "Eight", 0 };
- char *flowtext[] = { "Disabled", "Enabled", 0 };
-
- /* Open window pointers */
- struct WINDOW *tty, *status;
-
- /* Global window pointer (to retain postion) */
- int main_p = 0, config_p = 0, serial_p = 0, proto_p = 0, script_p = 0;
-
- /* Misc global variables */
- int signals = SET_DTR|SET_RTS|OUTPUT_2;
- int key_delay = 0, status_name_ptr = 0;
- char *key_ptr = 0, *status_names[10], sent_cr, last_rx;
- char cnffile[FSIZE+1] = { "LAPTALK" };
- FILE *fp, *log_fp = 0, *upl_fp = 0; /* Upload/Download file pointers */
-
- /* Globals used by the script interpreter */
- unsigned line, cptr = 0, savenv[3];
- char *optr, capture[CAPTURE_SIZE], invisible, abort_flag, interactive = -1;
- char buffer[80];
-
- extern register message_box(), write_status();
-
- /*
- * Main program
- */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- optr = cnffile;
- for(line=1; line < argc; ++line) {
- tty = argv[line];
- switch((*tty++ << 8)|*tty++) {
- case 'c=' : /* Specify CONFIG file */
- case 'C=' :
- optr = tty;
- break;
- case '-i' : /* Disable interactive session */
- case '-I' :
- interactive = 0;
- break;
- case '-?' :
- case '?' << 8:
- abort("\nUse: LAPTALK [-i c=file] [script command]\n\nCopyright 1991-1994 Dave Dunfield\nAll rights reserved.\n");
- default:
- while(argc < 20)
- argv[argc++] = 0;
- argc = 0; } }
-
- parse_filename(buffer, cnfext);
- if(fp = fopen(buffer, "rb")) {
- fread(homedir, ansi_keys-homedir, fp);
- fclose(fp); }
-
- status = wopen(0, 24, 80, 1, attrs[STATUS]);
- tty = wopen(0, 0, 80, 24, attrs[TTY]);
-
- if(!fp)
- message_box("Unable to open CONFIG file: %s", buffer);
-
- update_status();
- w_puts(" Press CTRL-HOME or CTRL-END for menu", status);
-
- open_comm();
- IOB_size = 512;
-
- if(!argc)
- script(&argv[line-1]);
-
- while(interactive) {
- ansi_term();
- if(!wmenu(5, 3, attrs[SETUP1], main_menu, &main_p)) switch(main_p) {
- case 0 : /* Fast access script */
- if(optr = file_menu(scripts, &script_p, 0)) {
- parse_args(buffer);
- script(buffer); }
- break;
- case 1 : /* Download */
- if(optr = file_menu(protocols, &proto_p, 0))
- file_transfer(0, 0);
- break;
- case 2 : /* Upload */
- if(optr = file_menu(protocols, &proto_p, 0))
- file_transfer(-1, 0);
- break;
- case 3 : /* Close capture */
- if(log_fp)
- fclose(log_fp);
- log_fp = 0;
- update_status();
- break;
- case 4 : /* Script by name */
- if(!get_string("Script", optr = scriptfile, FSIZE)) {
- parse_args(buffer);
- script(buffer); }
- break;
- case 5 : /* Hangup */
- hangup();
- break;
- case 6 : /* Clear screen */
- wclwin();
- break;
- case 7 : /* Configure */
- configure();
- break;
- case 8 : /* Shell to DOS */
- doshell(0);
- break;
- case 9 : /* Exit */
- interactive = 0; } }
-
- if(log_fp)
- fclose(log_fp);
- if(hangmdm) {
- signals &= ~(SET_DTR|SET_RTS);
- open_comm(); }
- Cclose();
- wclose();
- wclose();
- }
-
- /*
- * Display a message in a box
- */
- register message_box(args)
- unsigned args;
- {
- unsigned *ptr, l;
- char buffer[80];
-
- ptr = nargs() * 2 + &args;
- _format_(buffer, ptr);
-
- l = strlen(buffer)+16;
- wopen((80-l)/2, 10, l+2, 3, attrs[ERROR]);
- wcursor_off();
- wprintf(" %s (Press ENTER) ", buffer);
- if(alarm) wputc(7);
- while(wgetc() != '\n');
- wclose();
- }
-
- /*
- * Write a message into the status line
- */
- register write_status(args)
- unsigned args;
- {
- unsigned *ptr;
- char buffer[80];
-
- ptr = nargs() * 2 + &args;
- _format_(buffer, ptr);
- w_printf(status,"\r%s", buffer);
- w_cleow(status);
- }
-
- /*
- * Update status line
- */
- update_status()
- {
- int i;
- w_printf(status,"\rCOM%u: %5s-%u%c%u %c \xB3 %3s \xB3",
- com_port+1, baudtext[baud], dbits+5, *paritytext[parity], sbits+1,
- *flowtext[flow], log_fp ? "Cap" : "");
- for(i=0; i < status_name_ptr; ++i)
- w_printf(status," %s", status_names[i]);
- w_cleow(status);
- }
-
- /*
- * Open comm port with correct settings
- */
- open_comm()
- {
- int mode;
-
- /* Calculate the communications parameter value */
- mode = ((parity << 4) & 0x30) | /* parity type */
- (dbits & 0x03) | /* # data bits */
- ((sbits << 2) & 0x04) | /* # stop bits */
- ((parity < 4) << 3); /* parity enable */
-
- /* Open the communications port */
- if(Copen(com_port+1, baudvalue[baud], mode, signals)) {
- message_box("Cannot open COM port %u!", com_port+1);
- return 0; }
-
- /* Remove transparency if XON/XOFF flow control */
- disable();
- Cflags = (flow) ? Cflags & ~TRANSPARENT : Cflags | TRANSPARENT;
- enable();
-
- return -1;
- }
-
- /*
- * Hangup the modem
- */
- hangup()
- {
- write_status("Hanging up the modem...");
- signals &= ~(SET_DTR|SET_RTS);
- open_comm();
- wait_clear(hangup_delay);
- signals |= (SET_DTR|SET_RTS);
- open_comm();
- update_status();
- }
-
- /*
- * Write a string to the comm port
- */
- Cputs(ptr)
- char *ptr;
- {
- int c;
- unsigned timeout;
-
- while(*ptr) {
- timeout = key_string_delay;
- do {
- if((c = Ctestc()) != -1)
- receive_data(c);
- if((c = Ctestc()) != -1)
- receive_data(c); }
- while(timeout--);
- Cwrite(*ptr++); }
- testabort();
- }
-
- /*
- * Write char to comm port with echo if enabled
- */
- Cwrite(c)
- int c;
- {
- Cputc(c);
- if(echosnd)
- wputc(c);
- }
-
-
- /*
- * Get a string from the console
- */
- get_string(prompt, name, length)
- char *prompt, *name;
- int length;
- {
- int i, j;
-
- i = (j = strlen(prompt))+length+7;
- wopen((80-i)/2, 10, i, 3, attrs[STRING]);
- for(;;) {
- wgotoxy(1, 0);
- wprintf("%s ? ", prompt);
- switch(wgets(j+4, 0, name, length)) {
- case 0x1B : /* Exit */
- wclose();
- return -1;
- case '\n' : /* Select */
- wclose();
- return 0; } }
- }
-
- /*
- * Open a file with options
- */
- open_file(filename, options)
- char *filename, *options;
- {
- int n, p, c, i;
- char *names[100], namebuf[1000], *nptr, *ptr, *ptr1;
-
- for(ptr = filename; i = *ptr; ++ptr)
- if((i == '*') || (i == '?'))
- break;
- if(i) {
- if(find_first(filename, n = 0, nptr = namebuf, &i, &i, &i, &i, &i)) {
- message_box("No files found matching: '%s'", filename);
- return 0; }
- wopen(13, 5, 53, 12, attrs[STRING]);
- wcursor_off();
- do {
- for(i=0; i < n; ++i)
- if(strcmp(names[i], nptr) == 1)
- break;
- for(c = ++n; c > i; --c)
- names[c] = names[c-1];
- names[i] = nptr;
- while(*nptr++); }
- while((n < (sizeof(names)/2)) && !find_next(nptr, &i, &i, &i, &i, &i));
- for(i=n; i < (sizeof(names)/2); ++i)
- names[i] = "";
-
- c = p = 0;
- for(;;) {
- for(i=0; i < 40; ++i) {
- wgotoxy((i%4)*13, i/4);
- *W_OPEN = (i == c) ? ((*W_OPEN >> 4)|(*W_OPEN << 4)) : attrs[STRING];
- wputf(names[i+p], 12); }
- switch(wgetc()) {
- case 0x1B :
- wclose();
- return 0;
- case '\n' :
- ptr = ptr1 = filename;
- while(i = *ptr++) {
- if((i == '\\') || (i == ':'))
- ptr1 = ptr; }
- strcpy(ptr1, names[p+c]);
- wclose();
- goto open_file;
- case _KRA : i = c + 1; goto position;
- case _KLA : i = c - 1; goto position;
- case _KUA : i = c - 4; goto position;
- case _KDA : i = c + 4;
- position:
- if(i < 0) {
- c = 0;
- if((p - 4) >= 0) {
- c = i + 4;
- p -= 4; }
- break; }
- if(i >= 40) {
- if((p + 40) < n) {
- i -= 4;
- p += 4; } }
- c = ((p + i) < n) ? i : (n - p) - 1; } } }
-
- open_file:
- if(!options) /* Solve wildcards only ... don't open */
- return -1;
- if(!(fp = fopen(filename, options)))
- message_box("Unable to access: '%s'", filename);
- return fp;
- }
-
- /*
- * Configuration menu
- */
- configure()
- {
- int c, i, f, b;
- char *ptr;
-
- wopen(5, 3, 30, (sizeof(config_menu)/2)+1, WSAVE);
- wcursor_off();
- while(!wmenu(5, 3, attrs[SETUP2], config_menu, &config_p)) switch(config_p) {
- case 0 : /* General switches */
- ptr = &alarm;
- wopen(28, 3, 40, (sizeof(switches)/2)+2, attrs[SETUP1]);
- for(;;) {
- for(i=0; i < (sizeof(switches)/2); ++i) {
- wgotoxy(0, i);
- wprintf("%u: %-31s= %c", i+1, switches[i], ptr[i] ? 'Y' : 'N'); }
- if((i = wgetc()) == 0x1B) {
- wclose();
- break; }
- if((i -= '1') < (sizeof(switches)/2))
- ptr[i] = ptr[i] ? 0 : -1; }
- break;
- case 1 : /* General parameters */
- wform(28, 3, attrs[SETUP1], setup_form, homedir, &tab_size, &hangup_delay,
- &key_string_delay, &upl_char_delay, &upl_line_delay, &upl_sync_char);
- break;
- case 2 : /* Serial port setup */
- wopen(28, 3, 30, (sizeof(serial_menu)/2)+1, WSAVE);
- while(!wmenu(28, 3, attrs[SETUP2], serial_menu, &serial_p)) {
- switch(serial_p) {
- case 0 : wmenu(42, 3, attrs[SETUP1], onefour, &com_port); break;
- case 1 : wmenu(42, 3, attrs[SETUP1], baudtext, &baud); break;
- case 2 : wmenu(42, 3, attrs[SETUP1], paritytext, &parity); break;
- case 3 : wmenu(42, 3, attrs[SETUP1], fiveight, &dbits); break;
- case 4 : wmenu(42, 3, attrs[SETUP1], onetwo, &sbits); break;
- case 5 : wmenu(42, 3, attrs[SETUP1], flowtext, &flow); }
- update_status(); }
- open_comm();
- wclose();
- break;
- case 3 : /* Protocol setup */
- wform(5, 13, attrs[SETUP1], string_form, protocols[0], protocols[1],
- protocols[2], protocols[3], protocols[4], protocols[5],
- protocols[6], protocols[7]);
- break;
- case 4 : /* Script setup */
- wform(5, 13, attrs[SETUP1], string_form, scripts[0], scripts[1],
- scripts[2], scripts[3], scripts[4], scripts[5], scripts[6],
- scripts[7]);
- break;
- case 5 : /* Video attributes */
- i = 0;
- do {
- f = attrs[i] & 0x0F;
- b = (attrs[i] >> 4) & 0x0F;
- wopen(28, 3, 40, 9, WSAVE|WCOPEN|WBOX2|(b<<4)|f);
- *W_OPEN = (f << 4) + b;
- wprintf("%-38s\n\n", menus[i]);
- *W_OPEN = (b << 4) + f;
- wputs("Left/Right = Foreground\nUp/Down = Background\n");
- wputs("PgUp/PgDn = Select window\n\nPress ESCAPE to exit.");
- c = wgetc();
- wclose();
- switch(c) {
- case _KRA : f = (f+1) & 0x0F; goto newattr;
- case _KLA : f = (f-1) & 0x0F; goto newattr;
- case _KDA : b = (b+1) & 0x0F; goto newattr;
- case _KUA : b = (b-1) & 0x0F;
- newattr:
- attrs[i] = (attrs[i] & 0xff00) | (b << 4) | f;
- break;
- case _KPD : if(++i >= (sizeof(menus)/2)) i = 0; break;
- case _KPU : if(--i < 0) i = (sizeof(menus)/2)-1; } }
- while(c != 0x1B);
- break;
- case 6 : /* Load configuration */
- if(get_string(cnfprompt, optr = cnffile, FSIZE))
- break;
- parse_filename(buffer, cnfext);
- if(open_file(buffer, "rb")) {
- fread(homedir, ansi_keys-homedir, fp);
- fclose(fp);
- open_comm(); }
- break;
- case 7 : /* Save configuration */
- if(get_string(cnfprompt, optr = cnffile, FSIZE))
- break;
- parse_filename(buffer, cnfext);
- if(open_file(buffer, "wb")) {
- fwrite(homedir, ansi_keys-homedir, fp);
- fclose(fp); }
- }
- wclose();
- update_config();
- }
-
- /*
- * Update the displays to indiate a new configuration
- */
- update_config()
- {
- if(*tty != (*attrs & 0xff)) {
- *tty = *attrs;
- w_clwin(tty); }
- *status = attrs[STATUS];
- update_status();
- }
-
- /*
- * Terminal mode using ANSI (VT100) emulation
- */
- ansi_term()
- {
- char c, xy_flag;
- unsigned x, y, state, value, parm, parms[5];
-
- xy_flag = -1; /* Force initial cursor update */
- state = 0; /* Not receiving a control sequence */
- for(;;) {
- /* Process any input from the comm port */
- if((c = Ctestc()) != -1) {
- last_rx = c;
- ansi_out:
- if(log_fp && ((c >= ' ') || (c == '\t') || (c == '\n')))
- putc(c, log_fp);
- xy_flag = -1;
- if(c == 0x1B) { /* Begin escape sequence */
- state = 1;
- parms[0] = parms[1] = value = parm = 0; }
- else switch(state) {
- case 1 : /* Escape already received */
- if(c == '[') {
- state = 2;
- break; }
- state = 0;
- case 0 : /* No special processing */
- if(c == '\t') {
- do
- wputc(' ');
- while(tty[6] % tab_size);
- break; }
- wputc(c);
- break;
- case 2 : /* Waiting for numeric parms */
- if(isdigit(c)) {
- value = (value * 10) + (c - '0');
- break; }
- parms[parm++] = value; /* More to come */
- if(c == ';') {
- value = 0;
- break; }
- state = 0;
- switch(c) {
- case 'H' : /* Cursor position (1) */
- case 'f' : /* Cursor position (2) */
- if(y = parms[0])
- --y;
- if(x = parms[1])
- --x;
- wgotoxy(x, y);
- break;
- case 'J' : /* Erase in display */
- x = tty[6]; y = tty[7];
- value ? wclwin() : wcleow();
- tty[6] = x; tty[7] = y;
- break;
- case 'K' : /* Erase in line */
- if(value)
- tty[6] = 0;
- wcleol();
- break;
- case 'm' : /* Select attributes */
- if((x = parms[0]) > 7)
- x = 0;
- *tty = attrs[x]; } } }
- else if(xy_flag) { /* Cursor has moved */
- wupdatexy();
- xy_flag = 0; }
-
- /* Process any input from the keyboard */
- if(c = get_key()) {
- if(c == EOF)
- return;
- Cputc(c);
- if(echotty)
- goto ansi_out; } }
-
- }
-
- /*
- * Read a key from the keyboard
- */
- get_key()
- {
- int c;
-
- if(key_delay) {
- --key_delay;
- return 0; }
-
- if(upl_fp) {
- if(c = wtstc()) switch(c) {
- case 0x1B :
- abort_flag = -1;
- goto abort;
- case ' ' :
- last_rx = upl_sync_char; }
- key_delay = upl_char_delay;
- switch(sent_cr) {
- case ' ' : /* Expanded NULL line */
- goto sendcr;
- case '\r' : /* Just sent return */
- if(sendlf)
- return sent_cr = 0x0A;
- case 0x0A : /* Just sent line-feed */
- if(upl_sync_char) {
- if(last_rx != upl_sync_char)
- return key_delay = 0; }
- sent_cr = -1; }
- if((c = getc(upl_fp)) != EOF) {
- if(c == '\n') {
- if(sendnull && sent_cr)
- return sent_cr = ' ';
- sendcr: key_delay = upl_line_delay;
- return sent_cr = '\r'; }
- sent_cr = 0;
- return c; }
- abort: fclose(upl_fp);
- upl_fp = sent_cr = 0;
- update_status(); }
- if(key_ptr) {
- if(c = *key_ptr++) {
- key_delay = key_string_delay;
- return c; }
- key_ptr = 0; }
- if((c = wtstc()) & 0x80) {
- return (key_ptr = ansi_keys[c & 0x7f]) ? 0 : -1; }
- return (c == '\n') ? '\r' : c;
- }
-
- /*
- * Execute a sub-shell
- */
- doshell(command)
- char *command;
- {
- char comspec[65], tail[80];
-
- if(!getenv("COMSPEC", comspec)) {
- message_box("Cannot locate COMSPEC");
- return; }
- *tail = 0;
- if(command)
- concat(tail, "/C ", command);
- wopen(0, 0, 80, 25, WSAVE|WCOPEN|0x07);
- wupdatexy();
- exec(comspec, tail);
- wclose();
- }
-
- /*
- * Perform a file transfer
- */
- file_transfer(upload, name)
- char upload, *name;
- {
- int i, c;
- char buffer[6], cmd[100], zap, wait, ascii;
- char *ptr1, *ptr2, *ptr3;
-
- wait = zap = ascii = i = 0;
- ptr1 = parse_filename(cmd, ".COM");
-
- ptr2 = ++ptr1;
- while(c = *optr++) {
- if(c == '\\') switch(c = *optr++) {
- case 'Z' : zap = -1; continue; /* Zap screen */
- case 'W' : wait = -1; continue; /* Wait after run */
- case 'A' : ascii = -1; continue; /* ASCII transfer */
- case 'P' : ptr3 =paritytext[parity];goto copy; /* Parity */
- case 'B' : ptr3 = baudtext[baud]; goto copy; /* Baudrate */
- case 'H' : ptr3 = homedir; goto copy; /* Home dir */
- case 'N' : c = dbits + 5; goto wrnum; /* Data bits */
- case 'S' : c = sbits + 1; goto wrnum; /* Stop bits */
- case 'C' : c = com_port + 1; /* Comm port */
- wrnum:
- sprintf(ptr3 = buffer,"%u", c);
- copy:
- while(c = *ptr3++)
- *ptr1++ = c;
- continue;
- case 'G' : /* Upload filename */
- case 'Y' : /* Upload with wildcards */
- if(!upload)
- continue;
- case 'F' : /* Filename */
- case 'X' : /* Allow wildcards */
- if(!(ptr3 = name)) {
- if(get_string(upload ? uplprompt : dnlprompt, ptr3 = name = filename, FSIZE))
- return; }
- if(((c == 'F') || (c == 'G')) && !open_file(name, 0))
- return;
- goto copy;
- case 'U' : /* Upload string */
- while((c = *optr++) && (c != '\\'))
- if(upload)
- *ptr1++ = c;
- continue;
- case 'D' : /* Download string */
- while((c = *optr++) && (c != '\\'))
- if(!upload)
- *ptr1++ = c;
- continue; }
- *ptr1++ = c; }
- *ptr1 = 0;
-
- /* Process ASCII transfers */
- if(ascii) {
- while(isspace(*ptr2)) ++ptr2;
- if(upload) {
- if(upl_fp = open_file(ptr2, "r"))
- write_status("ASCII upload of '%s'...", ptr2); }
- else {
- if(log_fp)
- fclose(log_fp);
- log_fp = open_file(ptr2, "w");
- update_status(); }
- return; }
-
- /* Execute the external protocol */
- write_status("%s of '%s'...", upload ? "Upload" : "Download", name);
- Cclose();
- if(zap) wopen(0, 0, 80, 25, WSAVE|WCOPEN|0x07);
- wupdatexy();
- i = exec(cmd, ptr2);
- if(wait) {
- write_status("Press enter to continue...");
- while(wtstc() != '\n'); }
- if(zap) wclose();
- open_comm();
- update_status();
- if(i)
- message_box("Error %u returned from '%s'!", i, cmd);
- }
-
- /*
- * Build an entry from a file list
- */
- file_menu(files, pointer, name)
- char files[NFILES][FWIDTH], *name;
- int *pointer;
- {
- int i, j, c;
- char *names[NFILES+1], *pptr[NFILES], buffer[100], *ptr, *ptr1, *ptr2;
-
- /* Build menu from filenames */
- ptr1 = buffer;
- for(i=j=0; i < NFILES; ++i) {
- if(*(ptr = files[i])) {
- pptr[j] = ptr;
- names[j++] = ptr2 = ptr1;
- while(c = *ptr++) {
- if(isspace(c) || (c == ';'))
- break;
- else if((c == '\\') || (c == ':'))
- ptr1 = ptr2;
- else
- *ptr1++ = c; }
- *ptr1++ = 0; }
- if(name && strbeg(ptr2, name)) {
- ptr = ptr1 = pptr[j-1];
- goto strip_name; } }
- names[j] = 0;
-
- if(!j) {
- message_box("No selections configured!");
- return 0; }
-
- if(wmenu(5, 3, attrs[SETUP1], names, pointer))
- return 0;
-
- /* Strip off any leading name */
- ptr = ptr1 = pptr[*pointer];
- strip_name:
- while((c = *ptr++) && !isspace(c)) {
- if(c == ';')
- return ptr; }
- return ptr1;
- }
-
- /*
- * Execute a script command file
- */
- script(argv)
- char *argv[];
- {
- unsigned c, i;
- char buffer[80], buffer1[80], *ptr, *ptr1;
- char variables[NUM_VARS][50];
- FILE *sfp;
-
- chain_script:
- abort_flag = invisible = 0;
- status_names[status_name_ptr++] = optr = argv[0];
- parse_filename(buffer, ".SCR");
- if(!(sfp = open_file(buffer, "r")))
- goto exit1;
- update_status();
-
- /* zero out the variables */
- for(line=i=0; i < NUM_VARS; ++i)
- *variables[i] = 0;
- flush_capture(0);
-
- while(fgets(optr = buffer, sizeof(buffer), sfp)) {
- ++line;
- /* Skip any label */
- if(skip_blanks() == ':')
- while(*optr && !isspace(*optr))
- ++optr;
-
- next_cmd_string:
- wupdatexy();
- /* Substitute any variables etc. */
- ptr = buffer1;
- while((c = *optr++) && (c != ';')) {
- if(c == '\\') switch(c = *optr++) {
- case 'b' : c = 0x08; break;
- case 'd' : c = 0x7F; break;
- case 'e' : c = 0x1B; break;
- case 'r' : c = 0x0D; break;
- case '#' :
- c = 0;
- while(isdigit(*optr))
- c = (c*10) + (*optr++ - '0');
- break;
- case 's' :
- sprintf(ptr, "%u", Csignals());
- while(*++ptr);
- continue;
- default:
- if((i = c - '0') < 10)
- ptr1 = argv[i];
- else if((i = c - 'A') < NUM_VARS)
- ptr1 = variables[i];
- else if(c == 'n')
- ptr1 = "\r\n";
- else if(c == 'h')
- ptr1 = homedir;
- else
- break;
- if(ptr1) while(*ptr1)
- *ptr++ = *ptr1++;
- continue; }
- else if(c == '^')
- c = *optr++ & 0x1f;
- *ptr++ = c; }
- while(isspace(*--ptr) && (ptr >= buffer1));
- *++ptr = 0;
- optr = buffer1;
-
- continue_command:
- testabort();
- if(abort_flag)
- goto exit;
- if(*optr) switch(i = lookup(commands)) {
- case 0 : /* Print */
- wprintf("%s\n\r",optr);
- break;
- case 1 : /* Echo */
- wputs(optr);
- break;
- case 2 : /* Assign */
- case 3 : /* Equate */
- case 4 : /* Input */
- case 5 : /* Read */
- case 6 : /* Menu */
- if((c = *optr++ - 'A') >= NUM_VARS) {
- script_error("Invalid variable name");
- goto exit; }
- skip_blanks();
- ptr = variables[c];
- switch(i) {
- case 2 : strcpy(ptr, optr); break;
- case 3 : sprintf(ptr, "%d", eval()); break;
- case 4 :
- if(get_string(optr, ptr, sizeof(variables[0])-1))
- goto exit;
- break;
- case 5 :
- Cputs(optr);
- i = 0;
- do {
- do
- if(testabort()) goto exit;
- while((c = Ctestc()) == -1);
- if((c == '\b') || (c == 0x7f)) {
- if(i) {
- --i;
- Cputs("\b \b"); } }
- else if(c >= ' ')
- Cwrite(ptr[i++] = c); }
- while(c != '\r');
- ptr[i] = 0;
- Cputs("\n\r");
- break;
- case 6 :
- parse_args(buffer);
- c = 0;
- sprintf(ptr,"%d", wmenu(5, 3, attrs[SETUP1], buffer, &c) ?
- -1 : c); }
- break;
- case 7 : /* If# */
- if(eval()) {
- expect(':');
- goto continue_command; }
- break;
- case 8 : /* Ifeq */
- case 9 : /* ifne */
- parse_string(buffer);
- parse_string(buffer+40);
- expect(':');
- if(i == 8) {
- if(!strcmp(buffer, buffer+40))
- goto continue_command; }
- else {
- if(strcmp(buffer, buffer+40))
- goto continue_command; }
- break;
- case 10 : /* Ifnot */
- parse_string(buffer);
- expect(':');
- if(!search_buffer(buffer))
- goto continue_command;
- break;
- case 11 : /* If */
- parse_string(buffer);
- expect(':');
- if(search_buffer(buffer))
- goto continue_command;
- break;
- case 12 : /* Goto */
- if(*optr == '+')
- ++optr;
- else {
- rewind(sfp);
- line = 0; }
- ptr = optr;
- search_next:
- while(fgets(optr = buffer, sizeof(buffer), sfp)) {
- ++line;
- if(skip_blanks() == ':') {
- ++optr;
- ptr1 = ptr;
- while(*optr && !isspace(*optr)) {
- if(*optr++ != *ptr1++)
- goto search_next; }
- if(isspace(*ptr1) || !*ptr1)
- goto next_cmd_string; } }
- script_error("Label not found");
- case 13 : /* Skip */
- for(i = eval(); i; --i)
- if(!fgets(buffer, sizeof(buffer), sfp))
- goto exit;
- case 14 : /* Stop */
- goto exit;
- case 15 : /* Call */
- i = line;
- c = invisible;
- parse_args(buffer);
- script(buffer);
- invisible = c;
- line = i;
- break;
- case 16 : /* Chain */
- fclose(sfp);
- parse_args(argv);
- --status_name_ptr;
- goto chain_script;
- case 17 : /* Send */
- Cputs(optr);
- break;
- case 18 : /* Scan */
- flush_capture(0);
- if(parse_string(buffer))
- if(!wait_string(buffer, eval()+1))
- if(*optr) {
- expect(':');
- goto continue_command; }
- break;
- case 19 : /* Flush */
- while((c = Ctestc()) != -1)
- receive_data(c);
- flush_capture(*buffer ? buffer : 0);
- break;
- case 20 : /* Wait */
- wait_clear(eval());
- break;
- case 21 : /* Upload */
- case 22 : /* Download */
- ptr = optr;
- while((c = *optr) && !isspace(c)) ++optr;
- if(c)
- *optr++ = 0;
- ptr1 = skip_blanks() ? optr : 0;
- if(optr = file_menu(protocols, &proto_p, ptr)) {
- if(i == 21) {
- file_transfer(-1, ptr1);
- while(upl_fp) {
- while((c = Ctestc()) != -1)
- receive_data(c);
- if(c = get_key())
- Cwrite(c); } }
- else
- file_transfer(0, ptr1); }
- break;
- case 23 : /* Close */
- if(log_fp) {
- fclose(log_fp);
- log_fp = 0; }
- update_status();
- break;
- case 24 : /* Dos */
- doshell(optr);
- break;
- case 25 : invisible = 0; break; /* Visible */
- case 26 : invisible = -1; break; /* Invisible */
- case 27 : /* Abort */
- script_error(optr);
- break;
- case 28 : /* Error */
- abort_flag = -1;
- case 29 : /* Message */
- message_box(optr);
- break;
- case 30 : /* Hangup */
- hangup();
- break;
- case 31 : /* Terminal */
- ansi_term();
- break;
- case 32 : /* Clear */
- wclwin();
- break;
- case 33 : /* Config */
- parse_filename(buffer, cnfext);
- if(open_file(buffer, "rb")) {
- fread(homedir, ansi_keys-homedir, fp);
- fclose(fp);
- open_comm();
- update_config(); }
- break;
- case 34 : /* Exittodos */
- interactive = 0;
- abort_flag = -1;
- goto exit;
- default:
- script_error("Unknown command");
- goto exit;
- case 35 : } } /* Remark */
- exit:
- fclose(sfp);
- exit1:
- if(upl_fp) {
- fclose(upl_fp);
- upl_fp = 0; }
- --status_name_ptr;
- update_status();
- }
-
- /*
- * Evaluate an expression and return its numeric value
- */
- eval()
- {
- int o, v, v1;
- char vflag, mflag;
-
- v1 = o = 0;
- do {
- if(!*optr) {
- script_error("Incomplete expression");
- return 0; }
- mflag = vflag = v = 0;
- if(*optr == '-') {
- ++optr;
- mflag = -1; }
- if(*optr == '(') {
- ++optr;
- v = eval();
- if(expect(')'))
- return; }
- else {
- while(isdigit(*optr)) {
- v = (v * 10) + (*optr++ - '0');
- vflag = -1; }
- if(!vflag) {
- script_error("Invalid number");
- return 0; } }
- if(mflag) v = -v;
- switch(o) {
- case 0 : v1 += v; break;
- case 1 : v1 -= v; break;
- case 2 : v1 *= v; break;
- case 3 : v1 /= v; break;
- case 4 : v1 %= v; break;
- case 5 : v1 &= v; break;
- case 6 : v1 |= v; break;
- case 7 : v1 ^= v; break;
- case 8 : v1 <<= v; break;
- case 9 : v1 >>= v; break;
- case 10: v1 = v1 == v; break;
- case 11: v1 = v1 != v; break;
- case 12: v1 = v1 >= v; break;
- case 13: v1 = v1 <= v; break;
- case 14: v1 = v1 > v; break;
- case 15: v1 = v1 < v; }
- o = lookup(operators); }
- while(operators[o]);
- if((o = *optr) && (o != ':') && (o != ')')) {
- script_error("Invalid operation");
- return 0; }
- return v1;
- }
-
- /*
- * Determine if a character is a space
- */
- isspace(c)
- int c;
- {
- return (c == ' ') || (c == '\t');
- }
-
- /*
- * Lookup in table entry in command strinf
- */
- lookup(table)
- char **table;
- {
- int i;
- char *ptr;
-
- skip_blanks();
- for(i=0; ptr = table[i]; ++i)
- if(strbeg(optr, ptr)) {
- optr += strlen(ptr);
- break; }
- skip_blanks();
- return i;
- }
-
- /*
- * Skip ahead past leading blanks
- */
- skip_blanks()
- {
- while(isspace(*optr))
- ++optr;
- return *optr;
- }
-
- /*
- * Expect a character in the input buffer
- */
- expect(c)
- int c;
- {
- if(skip_blanks() == c) {
- ++optr;
- return 0; }
- script_error("Syntax error");
- return -1;
- }
-
- /*
- * Test for the abort key and indicate if pressed
- */
- testabort()
- {
- if(wtstc() == 0x1B) {
- script_error("User abort");
- return -1; }
- return 0;
- }
-
- /*
- * Indicate an error occuring in a script file
- */
- script_error(string)
- char *string;
- {
- wprintf("** line %u: %s\n\r", line, string);
- abort_flag = -1;
- }
-
- /*
- * Parse a delimited string from (optr)
- */
- parse_string(output)
- char *output;
- {
- int d, c;
- if(d = skip_blanks()) {
- while(c = *++optr) {
- if(c == d) {
- ++optr;
- *output = 0;
- skip_blanks();
- return -1; }
- *output++ = c; } }
- script_error("Improper string");
- return 0;
- }
-
- /*
- * Parse string(OPTR) into 10 ARGC, ARGV parameters
- */
- parse_args(outbuf)
- char *outbuf[];
- {
- int i;
- char *ptr;
-
- i = 0;
- ptr = &outbuf[10];
- while(skip_blanks()) {
- outbuf[i++] = ptr;
- while(*optr && !isspace(*optr))
- *ptr++ = *optr++;
- *ptr++ = 0; }
-
- while(i < 10)
- outbuf[i++] = 0;
- }
-
- /*
- * Parse a filename from (optr)
- */
- parse_filename(dest, suffix)
- char *dest, *suffix;
- {
- int c, d;
- char *ptr;
-
- /* Test for direcrtory supplied */
- d = '\\';
- ptr = optr;
- while((c = *ptr++) && !isspace(c)) {
- if((c == '\\') || (c == ':'))
- d = 0; }
- /* If no directory, prepend home directory */
- if(d) {
- ptr = homedir;
- while(c = *ptr++)
- *dest++ = d = c;
- if(d != '\\')
- *dest++ = '\\'; }
- /* Copy in filename */
- d = -1;
- while((c = *optr) && !isspace(c)) {
- ++optr;
- if((*dest++ = c) == '.')
- d = 0; }
- /* Append suffix if requested */
- if(d && suffix) {
- while(c = *suffix++)
- *dest++ = c; }
- *dest = 0;
- return dest;
- }
-
- /*
- * Flush the capture buffer and optionally insert a string
- */
- flush_capture(ptr)
- char *ptr;
- {
- register unsigned i;
-
- for(cptr = i = 0; i < CAPTURE_SIZE; ++i)
- capture[i] = 0;
- if(ptr) {
- while(*ptr)
- capture[cptr++] = *ptr++; }
- }
-
- /*
- * Handle data received from the remote
- */
- receive_data(c)
- char c;
- {
- capture[cptr] = last_rx = c;
- if(++cptr >= CAPTURE_SIZE)
- cptr = 0;
-
- /* echo char if selected */
- if(!invisible)
- wputc(c);
-
- /* Write download file if selected */
- if(log_fp && ((c >= ' ') || (c == '\t') || (c == '\n')))
- putc(c, log_fp);
- }
-
- /*
- * Wait for string from remote
- */
- wait_string(string, ticks)
- char *string;
- unsigned ticks;
- {
- int c;
- unsigned j, s, os;
- char *ptr, *ptr1, *ptr2, buffer[50], flag;
-
- os = -1;
- flag = 0;
- ptr = buffer;
-
- do {
- if((c = Ctestc()) >= 0) {
- receive_data(*ptr++ = c);
- *ptr = 0; flag = -1; }
- else if(testabort())
- return 0;
- if(flag) {
- ptr1 = string;
- ptr2 = buffer;
- while(*ptr2 && (*ptr2 == *ptr1)) {
- ++ptr1; ++ptr2; }
- if(*ptr2) { /* strings do not match at all */
- for(ptr1 = buffer; ptr1 < ptr; ++ptr1)
- *ptr1 = *(ptr1+1);
- --ptr; }
- else if(*ptr1) /* Partial match, wait for more chars */
- flag = 0;
- else /* Full match - we found it */
- return -1 ; }
- get_time(&j, &j, &s);
- if(s != os) {
- os = s;
- --ticks; } }
- while(ticks);
- return 0;
- }
-
- /*
- * Search the capture buffer for a string
- */
- search_buffer(string)
- char *string;
- {
- char *ptr;
- unsigned sptr, rptr;
-
- sptr = cptr;
-
- do {
- rptr = sptr;
- ptr = string;
- while(*ptr && (*ptr == capture[rptr])) {
- ++ptr;
- if(++rptr >= CAPTURE_SIZE)
- rptr = 0; }
-
- if(!*ptr) /* we found it */
- return 11;
- if(++sptr >= CAPTURE_SIZE) /* advance scan pointer */
- sptr = 0; }
- while(sptr != cptr);
- return 0;
- }
-
- /*
- * Wait until no data is received
- */
- wait_clear(ticks)
- unsigned ticks;
- {
- int c, t;
- unsigned j, s, os;
-
- os = -1;
- t = ++ticks;
- do {
- if((c = Ctestc()) != -1) {
- receive_data(c);
- t = ticks; }
- else {
- if(testabort())
- return;
- get_time(&j, &j, &s);
- if(s != os) {
- os = s;
- --t; } } }
- while(t);
- }
-